package com.rdgzs.framework.utilsTools;

import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Properties;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

/**
* ###################################################
* @创建日期：2012-12-4
* @开发人员：李广彬
* @功能描述：以classpath为基准来查找文件
* @修改日志：	
* ###################################################
*/
public class ClassLoaderUtil {
	private static Log log = LogFactory.getLog(ClassLoaderUtil.class);
	
	/**
	* ###################################################
	* @创建日期：2012-12-4
	* @开发人员：李广彬
	* @功能描述：加载Java类。 使用全限定类名
	* @传入参数：
	* @param className 加载类名
	* @return 加载类
	* ###################################################
	*/
	public static Class loadClass(final String className) {
		try {
			return getClassLoader().loadClass(className);
		} catch (ClassNotFoundException e) {
			throw new RuntimeException("class not found '" + className + "'", e);
		}
	}
	
	/**
	* ###################################################
	* @创建日期：2012-12-4
	* @开发人员：李广彬
	* @功能描述：得到类加载器
	* ###################################################
	*/
	public static ClassLoader getClassLoader() {
		return Thread.currentThread().getContextClassLoader();
	}
	
	/**
	 * ###################################################
	 * @创建日期：2012-12-4
	 * @开发人员：李广彬
	 * @功能描述：以相对路径的形式得到输入流内容
	 * @传入参数：
	 * @param relativePath 传入的带
	 * @return 文件输入流
	 * ###################################################
	 */
	public static InputStream getStream(final String relativePath) throws MalformedURLException, IOException {
		if (relativePath.contains("../")) {
			return ClassLoaderUtil.getStreamByExtendResource(relativePath);
		} else {
			return getClassLoader().getResourceAsStream(relativePath);
		}
	}
	
	/**
	  *
	  *@paramurl
	  *@return
	  *@throwsIOException
	  */
	public static InputStream getStream(URL url) throws IOException {
		if (url != null) {
			return url.openStream();
		} else {
			return null;
		}
	}
	
	/**
	 * ###################################################
	 * @创建日期：2012-12-4
	 * @开发人员：李广彬
	 * @功能描述：以相对路径的形式得到输入流内容的扩展  支持 ../../xxxx 的行式
	 * @传入参数：
	 * @param relativePath 对于classpath的路径
	 * @return 文件输入流
	 * ###################################################
	 */
	public static InputStream getStreamByExtendResource(final String relativePath) throws MalformedURLException,
			IOException {
		return ClassLoaderUtil.getStream(ClassLoaderUtil.getExtendResource(relativePath));
	}
	
	/**
	 *提供相对于classpath的资源路径，返回属性对象，它是一个散列表
	 *@paramresource
	 *@return
	 */
	public static Properties getProperties(final String resource) {
		Properties properties = new Properties();
		try {
			properties.load(getStream(resource));
		} catch (IOException e) {
			throw new RuntimeException("couldn't load properties file '" + resource + "'", e);
		}
		return properties;
	}
	
	/**
	  *得到本Class所在的ClassLoader的Classpat的绝对路径。
	  *URL形式的
	  *@return
	  */
	/**
	 * ###################################################
	 * @创建日期：2012-12-4
	 * @开发人员：李广彬
	 * @功能描述：得到本Class所在的ClassLoader的Classpat的绝对路径。
	 * @传入参数：
	 * @param relativePath 对于classpath的路径
	 * @return 资源的绝对URL
	 * ###################################################
	 */
	public static String getClassPath() {
		ClassLoaderUtil.log.info("当前的ClassPath:" + ClassLoaderUtil.getClassLoader().getResource("").toString());
		return getClassLoader().getResource("").toString();
		
	}
	
	/**
	 * ###################################################
	 * @创建日期：2012-12-4
	 * @开发人员：李广彬
	 * @功能描述：以相对路径的形式得到输入流内容的扩展  支持 ../../xxxx 的行式
	 *       1.支持多层路径模式 
	 *       2./是以classpath为基准 开始找文件 
	 *       3.直接以文件名 开始  在当前目录下查找文件
	 * @传入参数：
	 * @param relativePath 对于classpath的路径
	 * @return 资源的绝对URL
	 * ###################################################
	 */
	public static URL getExtendResource(final String relativePath) throws MalformedURLException {
		ClassLoaderUtil.log.info("传入的相对路径：" + relativePath);
		String classPath = ClassLoaderUtil.getClassPath();
		String resourceAbsolutePath = getAbsolutePath(classPath, relativePath);
		URL resourceAbsoluteURL = new URL(resourceAbsolutePath);
		return resourceAbsoluteURL;
	}
	
	/**
	 * ###################################################
	 * @创建日期：2012-12-4
	 * @开发人员：李广彬
	 * @功能描述：根据classpath 和相对路径 得到文件的绝对路径 
	 * @传入参数：
	 * @param relativePath 对于classpath的路径
	 * @return 资源的绝对URL
	 * ###################################################
	 */
	private static String getAbsolutePath(final String classpath, final String relativePath) {
		String[] pathGroups = relativePath.split("\\.\\.\\/");
		String absolutePath = classpath;
		for (int i = 1; i < pathGroups.length; i++) {
			absolutePath = absolutePath.substring(0, absolutePath.lastIndexOf("/", absolutePath.length() - 2) + 1);
		}
		absolutePath += pathGroups[pathGroups.length - 1];
		ClassLoaderUtil.log.info("转换后的绝对路径：" + absolutePath);
		return absolutePath;
	}
	
	/**
	 *@paramargs
	 *@throwsMalformedURLException
	 */
	public static void main(String[] args) throws MalformedURLException {
		//ClassLoaderUtil.getExtendResource("../spring/dao.xml");
		//ClassLoaderUtil.getExtendResource("../../../src/log4j.properties");
		ClassLoaderUtil.getExtendResource("log4j.properties");
		String kk = "../src/log4j.properties";
		ClassLoaderUtil.getExtendResource(kk);
		System.out.println(ClassLoaderUtil.getExtendResource(kk));
	}
}
